package ru.rchervot.sanasar.client.place;

import ru.rchervot.sanasar.client.event.EventPageChange;
import ru.rchervot.sanasar.client.event.HandlerPageChange;
import ru.rchervot.sanasar.client.model.FactoryQueryCandidates;
import ru.rchervot.sanasar.client.model.ResultsPage;
import ru.rchervot.sanasar.client.model.SearchResultsItem;
import ru.rchervot.sanasar.client.rpc.GetPage;
import ru.rchervot.sanasar.client.rpc.GotPage;
import ru.rchervot.sanasar.client.rpc.RPCServiceAsync;
import ru.rchervot.sanasar.client.view.RootPresenter;

import com.google.gwt.event.shared.HandlerManager;
import com.google.gwt.user.client.History;



public abstract class AbstractPlaceSearch extends AbstractPlace implements PlaceSearch {
		
	public static String getPlaceName() {
		return Constants.PLACE_NAME_SEARCH;
	}
	
	protected static final String DELIMITER = "/";
	private static final int START_PAGE_QUERY_ID = 0;
	private static final int START_PAGE_OFFSET = 0;
	
	protected int offset;
	protected int queryId;
		
	protected AbstractPlaceSearch(HandlerManager eventBus, RPCServiceAsync service, 
			String placeModule, FactoryQueryCandidates factoryQuery,
			RootPresenter  rootPresenter) {
		super(eventBus, service, placeModule, getPlaceName(),
				rootPresenter);
		
		listenForPageChange();
		
		//set start page parameters
		queryId = START_PAGE_QUERY_ID;
		offset = START_PAGE_OFFSET;
	}
	
	@Override
	protected String composePlaceParameters() {
		if (isStartPage()) {
			return null;
		} else {
			return queryId + DELIMITER + 
			(offset + 1); //because we send this offset to humans			
		}
	}
	
	private boolean isStartPage() {
		return queryId == 0;
	}
	
	@Override
	public void parseParameters(String parameters) {
		int newQueryId = START_PAGE_QUERY_ID;
		int newOffset = START_PAGE_OFFSET;
		
		if (parameters != null && parameters.length() > 0) {
			int LIMIT = 3;		// 1 qieryId, 2 offset, 3 other(not important)
			
			String[] sa = parameters.split(DELIMITER, LIMIT);
			
			try {
				newQueryId = Integer.valueOf(sa[0]);
				newOffset = Integer.valueOf(sa[1]);
				newOffset -= 1; //because this offset used by humans
			} catch (Exception ex) {
				System.out.println("Exception when parsing history token parameters: " + parameters);
			}
		}
		
		if (newQueryId > START_PAGE_QUERY_ID) {
			service.execute(new GetPage(newQueryId, newOffset),
					new GotPage<SearchResultsItem>() {
				public void got(ResultsPage<SearchResultsItem> page) {
				}
			});
		} 
//		else {
//			eventBus.fireEvent(EventPageChange.buildStartPage());
//		}
	}
	
	private void listenForPageChange() {
		eventBus.addHandler(EventPageChange.getType(),
				new HandlerPageChange<SearchResultsItem>() {
			@Override
			public void onPageChange(
					EventPageChange<SearchResultsItem> event) {
				if (event.isStartPage()) {
					updateHistory(START_PAGE_QUERY_ID, START_PAGE_OFFSET);
				} else {
					if (event.getPage().isEmpty()) {
						updateHistory(START_PAGE_OFFSET);
					} else {
						updateHistory(event.getPage().getQueryID(), event.getPage().getOffset());
					}					
				}
			}
		});
	}
	
	private void updateHistory(int offset) {
		if (this.offset != offset) {
			this.offset = offset;
			
			History.newItem(this.historyToken(), false);
		}
	}
	
	private void updateHistory(int queryId, int offset) {
		if (this.queryId != queryId || this.offset != offset) {
			this.queryId = queryId;
			this.offset = offset;
			
			History.newItem(this.historyToken(), false);
		}
	}
	
}
